第15天的實作是要利用LocalStorage來讓網頁關閉之後,資料不會移除,讓資料一直儲存在電腦中,以及Event Delegation。
在頁面表單可以輸入,因此在表單建立submit的事件,但是submit會造成畫面重整,因此要加入preventDefault()來取消submit事件觸發時造成的重整。
e.preventDefault();
此時的目標是當表單輸入完成後,觸發submit事件,讓畫面新增輸入的內容放置於ul元素中。
資料的內容包含輸入值以及輸入狀態,輸入狀態的內容為布林值。
const item = {
    name: this.querySelector('[name=item]').value,
    isDone: false,
  }
接下來是將表單中資料push到陣列中,再將陣列資料轉換為實體元素。
platesList.innerHTML = plates.map((plate, i) => {
  return `
    <li>
      <input type="checkbox" data-index=${i} id="item${i}" ${plate.done ? 'checked' : ''} />
      <label for="item${i}">${plate.text}</label>
    </li>
  `;
}).join('');
在動態建立的元素中以li包裹著兩個元素input[checkbox],label,因接下來透過input[checkbox]的點選來改變資料的狀態。
但此時發現重整畫面ul中的資料會消失,因此透過localStorage將資料存入,避免重整頁面而產生資料消失。
這時會發現直接將資料存入localStorage中會變成object格式,因此透過JSON.stringify()的方式轉換成文字,在儲存到localStorage中。
localStorage.setItem('items', JSON.stringify(items));
之後再取得localStorage資料要用JSON.parse()轉換成物件。
const items =  JSON.parse(localStorage.getItem('items')) || [];
接下來是建立click點選input[checkbox]即改變資料狀態的事件。
itemsList.addEventListener('click', toggleItem)
但此時會發現初始化所建立的li會有事件被觸發,但後來動態新增的li元素沒法觸發click事件。
原因是建立元素時是透過Element.innerHTML來加入內容,innerHTML是在該元素加入內容,但內容卻沒有包含事件。
為避免這問題的發生,就使用Event Delegation來作為解答」[1][2]。
Event Delegation的方式是指定在共同父層建立事件,當事件被觸發時,再去判斷為哪一個子元素被事件改變。
所先在事件中要先判斷是否符合input元素,若不是input元素則結束事件。
之後取得觸發事件的元素,並使用dataset取得index值,用index值來改變點選的狀態,再儲存轉換後的資料。
function toggleItem(e) {
  if (!e.target.matches('input')) return
  const el = e.target
  const index = el.dataset.index
  items[index].isDone = !items[index].isDone
  localStorage.setItem('items', JSON.stringify(items))
  showList(items, itemsList)
}
<ul class="plates">
  <li>Loading Tapas...</li>
</ul>
<form class="add-items">
  <input type="text" name="item" placeholder="Item Name" required>
  <input type="submit" value="+ Add Item">
</form>
Window.localStoragelocalStorageg類似於sessionStorage,但localStorageg可以不會有過時效,但sessionStorage網頁關閉時其資料內容會被完全清除。
Window.sessionStoragesessionStorage這個屬性讓開發人員將資料暫存在當下頁面(頁籤)的空間Storage物件裡。sessionStorage跟Window.localStorage很相似,唯一不同的地方是存放在localStorage的資料會永久保存,存放在sessionStorage的資料則會在頁面(頁籤)關閉時清空。只要該頁面頁面(頁籤)沒被關閉或者有還原(restore)該頁面,資料就會保存。
Event.preventDefault()
如果事件可以被取消,就取消事件(即取消事件的預設行為)。但不會影響事件的傳遞,事件仍會繼續傳遞。
Event.target
指向最初觸發事件的 DOM 物件。
HTMLFormElement
HTMLFormElement 介面提供了建立及修改 <form> 元素的方法。
HTMLFormElement.reset()
reset()方法將form元素中的內容回復成預設值。
HTMLFormElement.submit()
submit()方法提交form中的資料。
box-sizing
box-sizing 屬性用於更改預設 CSS 盒子模型 中所計算的寬度和高度。
content-box
這是根據 CSS 標準的起始值和預設值。 width  與  height 只包括內容本身的寬和高, 不包括邊框(border)、內邊距(padding)、外邊距(margin)。注意:內邊距、邊框和外邊距都在這個盒子的外部。
border-box
width 和 height 屬性包括內容(content),內邊距(padding)和邊框(border),但不包括外邊距(margin)。
localStorage, Event delegation